package com.dure.hotmemory.scenes.tzxl;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;
import android.text.TextUtils;

import com.dure.commonlib.util.AssetsUtil;
import com.dure.commonlib.util.PreferencesUtils;
import com.dure.hotmemory.R;
import com.dure.hotmemory.bean.Cell;
import com.dure.hotmemory.controllers.Controller;
import com.dure.hotmemory.drawview.BaseSurfaceView;
import com.dure.hotmemory.scenes.BaseScene;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by leix on 24/06/2017.
 */

public class CoupleImagesScene extends BaseScene {
    private float topStateHeight;
    private List<String> imgPathList;
    private ArrayList<Integer> selectedImgIndexList = new ArrayList<>();
    private ArrayList<Integer> shuffleIndexList = new ArrayList<>();
    private ArrayList<Cell> optionImgCellList = new ArrayList<>();
    private boolean showNext = true;
    private int showImageNumber = 2, totalImageNumber;
    private int currentShowIndex;// 当前展示的图片index
    private int currentSelectIndex; // 当前待选择的index;
    private long startTime;
    Paint paint;
    private boolean showNextOption;
    private RectF frameRectF = new RectF();
    private Cell selectedCell, wrongCell;
    private long selectedStartTime, restartWaitTime;
    private Bitmap heartBitmap;
    private int heartCount = 3;
    private String finishInfo;
    private boolean restart, startDraw;
    private RectF leftBtnRectF, rightBtnRectF;// 训练结束对话框的左右按钮区域
    Controller controller;
    boolean newRecordGet;
    public String alias;
    private int showCellIndex, correctNumber;
    private boolean wait, showOptions, startChose, gameOver, win;
    private int maxRowAndColumn = 6;
    private EmbossMaskFilter emboss;
    int[] colors = {Color.WHITE, Color.parseColor("#00BDFF")};

    public CoupleImagesScene(BaseSurfaceView baseSurfaceView) {
        super(baseSurfaceView);
        controller = new Controller(this);
        paint = new Paint();
        paint.setAntiAlias(true);
        imgPathList = AssetsUtil.getAssetsList(activity, "jdtx");
        totalImageNumber = imgPathList.size();
        heartBitmap = BitmapFactory.decodeResource(activity.getResources(), R.mipmap.heart);
        topStateHeight = baseSurfaceView.getWidth() * 0.12f;
        alias = PreferencesUtils.getString(activity, "current_alias");

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
            float[] direction = new float[] { 1, 1, 1 };
            // 设置环境光亮度
            float light = 0.5f;
            // 选择要应用的反射等级
            float specular = 10;// 这个参数更改没有看出效果上面的变化
            // 向mask应用一定级别的模糊
            float blur = 3;// 这个参数可以控制立体侧面的宽度
            emboss = new EmbossMaskFilter(direction, light, specular, blur);
            paint.setMaskFilter(emboss);
        }

        dataInited = true;
    }

    @Override
    public void handleData() {
        if (!dataInited) {
            return;
        }

        if (showNext) {
            showNext = false;
            if (showImageNumber > 18) {
                showImageNumber = 18;
            }
            startChose = false;
            correctNumber = 0;
            selectedImgIndexList = getRandomImagesIndex(showImageNumber, imgPathList.size());
            optionImgCellList = getCellList();
            wait = true;
            startTime = System.currentTimeMillis();
            startDraw = true;
        }

        if (wait && System.currentTimeMillis() - startTime > 1000) {
            wait = false;
            showCellIndex = 0;
            optionImgCellList.get(0).show = true;
            showOptions = true;
            startTime = System.currentTimeMillis();
        }

        if (showOptions && System.currentTimeMillis() - startTime > 1000) {
            startTime = System.currentTimeMillis();

            if (showCellIndex < optionImgCellList.size() - 1) {
                optionImgCellList.get(showCellIndex).show = false;
                showCellIndex++;
                optionImgCellList.get(showCellIndex).show = true;
            } else {
                optionImgCellList.get(showCellIndex).show = false;
                showOptions = false;
                startChose = true;
            }
        }

        if (wrongCell != null) {
            if (System.currentTimeMillis() - selectedStartTime > 1000) {
                selectedStartTime = System.currentTimeMillis();
                wrongCell.show = false;
                wrongCell.color = Color.WHITE;
                wrongCell = null;

                if (heartCount == 0) {
                    gameOver = true;
                    finishInfo = "挑战失败，请再接再厉！";
                }
            }
        }

        if (win && System.currentTimeMillis() - selectedStartTime > 1000) {
            selectedStartTime = System.currentTimeMillis();
            win = false;
            showImageNumber++;
            showNext = true;

        }

        if (restart && System.currentTimeMillis() - restartWaitTime > 1000){
            restart = false;
            heartCount = 3;
            showImageNumber = 2;
            showNext = true;
        }
    }


    private ArrayList<Integer> getRandomImagesIndex(int showNumber, int totalNumber) {
        ArrayList<Integer> indexList = new ArrayList<>();
        for (int i = 0; i < showNumber; i++) {
            int randomNum = (int) (Math.random() * totalNumber);

            while (indexList.contains(randomNum)) {
                randomNum = (int) (Math.random() * totalNumber);
            }

            indexList.add(randomNum);

        }

        return indexList;
    }

    private ArrayList<Cell> getCellList() {
        ArrayList<Cell> cellList = new ArrayList<>();


        float perImageSize = baseSurfaceView.getWidth() * 0.8f / maxRowAndColumn;
        float padding = baseSurfaceView.getWidth() * 0.2f / (maxRowAndColumn + 1);
        float frameSize = maxRowAndColumn * perImageSize + (maxRowAndColumn + 1) * padding;
        float frameTop = baseSurfaceView.getHeight() / 2 - frameSize / 2;
        float frameLeft = baseSurfaceView.getWidth() / 2 - frameSize / 2;
        frameRectF = new RectF(frameLeft, frameTop, baseSurfaceView.getWidth() - padding, frameTop + frameSize + 2 * padding);
        shuffleIndexList.clear();
        for (int i = 0; i < showImageNumber * 2; i++) {


            int randomIndex = (int) (Math.random() * maxRowAndColumn * maxRowAndColumn);
            while (shuffleIndexList.contains(randomIndex)) {
                randomIndex = (randomIndex + 1) % (maxRowAndColumn * maxRowAndColumn);
            }
            shuffleIndexList.add(randomIndex);

            int row = randomIndex / maxRowAndColumn;
            int column = randomIndex % maxRowAndColumn;
            float dstLeft = padding * (column + 1) + column * perImageSize + frameLeft;
            float dstTop = padding * (row + 1) + row * perImageSize + frameTop;
            float dstRight = dstLeft + perImageSize;
            float dstBottom = dstTop + perImageSize;
            String imagePath = imgPathList.get(selectedImgIndexList.get(i % showImageNumber));

            RectF dstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);

            Cell cell = new Cell();
            cell.index = i;
            cell.name = imagePath;
            cell.rectF = dstRect;
            cell.color = Color.WHITE;

            cellList.add(cell);

        }

//        Collections.shuffle(cellList);
        return cellList;
    }

    @Override
    public void handleDraw(Canvas canvas) {
        if (!dataInited) {
            return;
        }

        if (gameOver) {
            drawFinishDialog(canvas);
        } else if (startDraw){
            drawHeart(canvas);
            drawScore(canvas);
            drawSelectingImages(canvas);
        }


    }

    private void drawSelectingImages(Canvas canvas) {
        for (int i = 0; i < optionImgCellList.size(); i++) {
            Cell cell = optionImgCellList.get(i);

            paint.setColor(cell.color);
            float arc = cell.rectF.width() / 10;
            canvas.drawRoundRect(cell.rectF, arc, arc, paint);

            if (cell.show) {
                Bitmap bitmap = BitmapFactory.decodeStream(AssetsUtil.getAssets(activity, "jdtx/" + cell.name));
                drawShowingBitmap(canvas, bitmap, cell.rectF);
            }


        }
    }

    private void drawShowingBitmap(Canvas canvas, Bitmap bitmap, RectF dstRectF) {
        Rect srcRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

        float padding = dstRectF.width() * 0.1f;
        float dstLeft = dstRectF.left + padding;
        float dstTop = dstRectF.top + padding;
        float dstRight = dstRectF.right - padding;
        float dstBottom = dstRectF.bottom - padding;
        RectF newDstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);
        canvas.drawBitmap(bitmap, srcRect, newDstRect, null);
    }

    private void drawHeart(Canvas canvas) {
        Rect srcRect = new Rect(0, 0, heartBitmap.getWidth(), heartBitmap.getHeight());

        float dstHeartSize = topStateHeight * 0.8f;
        float leftPadding = topStateHeight * 0.2f;
        float topPadding = leftPadding;
        for (int i = 0; i < heartCount; i++) {
            float dstLeft = leftPadding * (i + 1) + i * dstHeartSize;
            float dstTop = topPadding;
            float dstRight = dstLeft + dstHeartSize;
            float dstBottom = dstTop + dstHeartSize;
            RectF dstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);

            canvas.drawBitmap(heartBitmap, srcRect, dstRect, null);
        }
    }


    private void drawScore(Canvas canvas) {

        String scoreStr = String.format("%d/%d", currentSelectIndex, selectedImgIndexList.size());
        String recordStr = String.format("Best:%d", PreferencesUtils.getInt(activity, alias + ":best", 0));

        float textSize = topStateHeight * 0.6f;
        paint.setTextSize(textSize);

        float scoreWidth = paint.measureText(scoreStr);
        float contentWidth = paint.measureText(recordStr);
        float rightPadding = topStateHeight * 0.2f;
        float topPadding = rightPadding;

        float contentLeft = canvas.getWidth() - rightPadding - contentWidth;
        float contentBottom = topPadding + textSize;

        paint.setColor(Color.WHITE);
        canvas.drawText(recordStr, contentLeft, contentBottom, paint);

        float scoreLeft = canvas.getWidth() / 2 - scoreWidth / 2;
        float scoreBottom = contentBottom;
        canvas.drawText(scoreStr, scoreLeft, scoreBottom, paint);
    }

    private void drawFinishDialog(Canvas canvas) {
        String infoStr = finishInfo;
        String exitStr = "退出";
        String continueStr = "重来";

        float dialogWidth = canvas.getWidth() * 0.8f;
        float dialogHeight = dialogWidth * 0.6f;
        float infoPartHeight = dialogHeight * 0.7f;
        float btnPartHeight = dialogHeight * 0.3f;

        float infoTextSize = dialogWidth * 0.8f / infoStr.length();

        // 绘制dialog frame
        float dialogLeft = canvas.getWidth() / 2 - dialogWidth / 2;
        float dialogTop = canvas.getHeight() / 2 - dialogHeight / 2;
        float dialogRight = canvas.getWidth() / 2 + dialogWidth / 2;
        float dialogBottom = canvas.getHeight() / 2 + dialogHeight / 2;
        RectF dialogRectF = new RectF(dialogLeft, dialogTop, dialogRight, dialogBottom);
        paint.setColor(Color.WHITE);
        float arc = dialogRectF.width() / 15;

        LinearGradient lg = new LinearGradient(dialogRectF.width() /2, 0, dialogRectF.width() /2, dialogRectF.height(), colors, null, Shader.TileMode.MIRROR);
        paint.setShader(lg);
        canvas.drawRoundRect(dialogRectF, arc, arc, paint);
        paint.setShader(null);

        // 绘制info
        paint.setTextSize(infoTextSize);
        float infoWidth = paint.measureText(infoStr);
        float infoLeft = canvas.getWidth() / 2 - infoWidth / 2;
        float infoBottom = dialogTop + infoPartHeight / 2 + infoTextSize / 2;
        paint.setColor(Color.RED);
        canvas.drawText(infoStr, infoLeft, infoBottom, paint);

        float btnWidth = dialogWidth * 0.3f;
        float btnHeight = btnWidth / 2.5f;
        float btnTextSize = btnHeight * 0.6f;

        // 绘制左边btn
        float leftBtnLeft = canvas.getWidth() / 2 - dialogWidth / 4 - btnWidth / 2;
        float leftBtnBottom = dialogBottom - btnPartHeight / 2 + btnHeight / 2;
        float leftBtnRight = leftBtnLeft + btnWidth;
        float leftBtnTop = leftBtnBottom - btnHeight;
        leftBtnRectF = new RectF(leftBtnLeft, leftBtnTop, leftBtnRight, leftBtnBottom);
        arc = leftBtnRectF.width() / 15;
        paint.setColor(Color.parseColor("#00BDFF"));
        canvas.drawRoundRect(leftBtnRectF, arc, arc, paint);

        paint.setTextSize(btnTextSize);
        float exitStrWidth = paint.measureText(exitStr);
        float exitLeft = leftBtnLeft + btnWidth / 2 - exitStrWidth / 2;
        float exitBottom = leftBtnBottom - btnHeight * 0.3f;
        paint.setColor(Color.WHITE);
        canvas.drawText(exitStr, exitLeft, exitBottom, paint);

        // 绘制右边btn
        float rightBtnLeft = canvas.getWidth() / 2 + dialogWidth / 4 - btnWidth / 2;
        float rightBtnBottom = leftBtnBottom;
        float rightBtnRight = rightBtnLeft + btnWidth;
        float rightBtnTop = leftBtnTop;
        rightBtnRectF = new RectF(rightBtnLeft, rightBtnTop, rightBtnRight, rightBtnBottom);
        arc = rightBtnRectF.width() / 15;
        paint.setColor(Color.parseColor("#00BDFF"));
        canvas.drawRoundRect(rightBtnRectF, arc, arc, paint);

        paint.setTextSize(btnTextSize);
        float continueStrWidth = paint.measureText(continueStr);
        float continueLeft = rightBtnLeft + btnWidth / 2 - continueStrWidth / 2;
        float continueBottom = rightBtnBottom - btnHeight * 0.3f;
        paint.setColor(Color.WHITE);
        canvas.drawText(continueStr, continueLeft, continueBottom, paint);
    }

    @Override
    public void handleDown(PointF pointF) {
        if (!startChose) {
            return;
        }

        if (gameOver) {
            if (leftBtnRectF.contains(pointF.x, pointF.y)) {
                gameOver = false;
                activity.backToLastScene();
            } else if (rightBtnRectF.contains(pointF.x, pointF.y)) {
                restart = true;
                startDraw = false;
                gameOver = false;
                selectedCell = null;
                restartWaitTime = System.currentTimeMillis();
//                showNext = true;
            }
        } else {
            if (wrongCell != null)
                return;
            // 先判断点击位置是否在frame内
            if (frameRectF.contains(pointF.x, pointF.y)) {
                // 再判断点击了哪个卡片
                for (int i = 0; i < optionImgCellList.size(); i++) {
                    Cell cell = optionImgCellList.get(i);
                    if (!cell.show && cell.rectF.contains(pointF.x, pointF.y)) {

                        if (selectedCell == null) {
                            selectedCell = cell;
                            selectedCell.show = true;
                        } else if (cell == selectedCell) {
                            selectedCell.show = false;
                            selectedCell.selected = false;
                            selectedCell = null;
                        } else {
                            cell.show = true;
                            cell.selected = true;

                            if (TextUtils.equals(cell.name, selectedCell.name)) {
                                cell.isCorrect = true;
                                selectedCell = null;
                                correctNumber++;
                                if (correctNumber == showImageNumber) {
                                    win = true;
                                    int oldBest = PreferencesUtils.getInt(activity, alias + ":best", 0);
                                    if (oldBest < showImageNumber) {
                                        PreferencesUtils.putInt(activity, alias + ":best", showImageNumber);
                                        newRecordGet = true;
                                    }
                                    selectedStartTime = System.currentTimeMillis();
                                }
                            } else {
                                cell.color = Color.RED;
                                cell.isCorrect = false;
                                wrongCell = cell;
                                heartCount--;
                                selectedStartTime = System.currentTimeMillis();
                            }

                        }
                        break;
                    }
                }
            }
        }


    }

    @Override
    public void handleBack() {
        if (PreferencesUtils.getBoolean(activity, "login_success")){
            if (newRecordGet) {
                int level = PreferencesUtils.getInt(activity, alias + ":best", 0);
                controller.uploadTrainingData(String.valueOf(level), alias);
            }
        }
    }
}
